use anyhow::{Context, Result};
use std::path::{Path, PathBuf};
use tokio::fs;

pub struct Storage {
    root_path: PathBuf,
    incoming_path: PathBuf,
    gpg_key_path: PathBuf,
}

impl Storage {
    pub async fn new(config: &crate::config::Config) -> Result<Self> {
        // 确保所有目录存在
        fs::create_dir_all(&config.storage.root_path).await?;
        fs::create_dir_all(&config.storage.incoming_path).await?;
        fs::create_dir_all(
            &config
                .storage
                .gpg_key_path
                .parent()
                .unwrap_or(Path::new(".")),
        )
        .await?;

        Ok(Self {
            root_path: config.storage.root_path.clone(),
            incoming_path: config.storage.incoming_path.clone(),
            gpg_key_path: config.storage.gpg_key_path.clone(),
        })
    }

    pub fn root_path(&self) -> &Path {
        &self.root_path
    }

    pub fn incoming_path(&self) -> &Path {
        &self.incoming_path
    }

    pub fn gpg_key_path(&self) -> &Path {
        &self.gpg_key_path
    }

    pub async fn save_incoming_file(
        &self,
        filename: &str,
        data: &[u8],
    ) -> Result<PathBuf> {
        let file_path = self.incoming_path.join(filename);
        fs::write(&file_path, data).await?;
        Ok(file_path)
    }

    pub async fn move_to_repository(&self, source: &Path, dest_path: &str) -> Result<PathBuf> {
        let full_dest = self.root_path.join(dest_path);
        
        if let Some(parent) = full_dest.parent() {
            fs::create_dir_all(parent).await?;
        }
        
        fs::rename(source, &full_dest).await?;
        Ok(full_dest)
    }

    pub async fn file_exists(&self, path: &str) -> bool {
        self.root_path.join(path).exists()
    }
}